package com.example.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.common.R;
import com.example.demo.common.SearchParam;
import com.example.demo.excel.ExcelUtil;
import com.example.demo.proxy.DataProxy;
import com.example.demo.proxy.DataProxyInvoke;
import com.example.demo.service.MyService;
import com.example.demo.util.GlobalUtil;
import com.example.demo.view.ModelView;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

@RestController
@RequestMapping("/common")
public class Controller {

    @Autowired
    private MyService myService;

    @Autowired
    private SqlSessionFactory sessionFactory;

    @Autowired
    private DataProxyInvoke dataProxyInvoke;

    @GetMapping("/view/{model}")
    public R view(@PathVariable String model) {
        Class clazz = GlobalUtil.entityClassMap.get(model);
        ModelView modelView = (ModelView) clazz.getAnnotation(ModelView.class);
        String order = modelView.order();
        if (order == null || order.equals("")) {
            order = model + ".id desc";
        }
        return R.ok(GlobalUtil.viewMap.get(model)).putExtra("order", order).putExtra("limit", modelView.limit());
    }

    //添加
    @PutMapping("/{model}")
    public R save(@PathVariable String model, @RequestBody JSONObject req) {
        Class clazz = GlobalUtil.entityClassMap.get(model);
        Object res = req.toJavaObject(req, clazz);
        DataProxy dataProxy = dataProxyInvoke.invoke(GlobalUtil.entityClassMap.get(model));
        if (dataProxy == null) {
            res = dataProxy.save(res);
        } else {
            res = myService.save(res);
        }
        return R.ok(res);
    }

    //修改
    @PatchMapping("/{model}")
    public R update(@PathVariable String model, @RequestBody JSONObject req) {
        Class clazz = GlobalUtil.entityClassMap.get(model);
        Object res = req.toJavaObject(req, clazz);
        DataProxy dataProxy = dataProxyInvoke.invoke(GlobalUtil.entityClassMap.get(model));
        if (dataProxy == null) {
            res = dataProxy.update(res);
        } else {
            res = myService.update(res);
        }
        return R.ok(res);
    }


    //查询
    @PostMapping("/{model}")
    public R list(@PathVariable String model, @RequestBody JSONObject req) {
        SearchParam searchParam = getSearchParam(model,req);
        List<Object> list;
        DataProxy dataProxy = dataProxyInvoke.invoke(GlobalUtil.entityClassMap.get(model));
        if (dataProxy == null) {
            list = dataProxy.list(searchParam);
        } else {
            PageHelper.startPage(searchParam.getPage(), searchParam.getLimit()).setOrderBy(searchParam.getOrder());
            list = myService.list(new QueryWrapper(searchParam.getEntity()));
        }
        return R.ok(new PageInfo<>(list));
    }


    //获取
    @GetMapping("/{model}/{id}")
    public R get(@PathVariable String model, @PathVariable Long id) {
        DataProxy dataProxy = dataProxyInvoke.invoke(GlobalUtil.entityClassMap.get(model));
        Object o;
        if (dataProxy == null) {
            o = dataProxy.get(id);
        } else {
            o = myService.get(model, id);
        }
        return R.ok(o);
    }

    //删除
    @DeleteMapping("/{model}")
    public R delete(@PathVariable String model, Long[] ids) {
        DataProxy dataProxy = dataProxyInvoke.invoke(GlobalUtil.entityClassMap.get(model));
        if (dataProxy == null) {
            dataProxy.delete(Arrays.asList(ids));
        } else {
            myService.delete(model, Arrays.asList(ids));
        }
        return R.ok();
    }


    //下载
    @PostMapping("/download/{model}")
    public void download(@PathVariable String model, @RequestBody JSONObject req, HttpServletResponse response) {
        SearchParam searchParam = getSearchParam(model,req);
        DataProxy dataProxy = dataProxyInvoke.invoke(GlobalUtil.entityClassMap.get(model));
        if (dataProxy == null) {
            dataProxy.download(searchParam, response);
        } else {
            PageHelper.startPage(searchParam.getPage(), searchParam.getLimit()).setOrderBy(searchParam.getOrder());
            myService.downLoad(new QueryWrapper(searchParam.getEntity()), response);
        }
    }

    @PostMapping("/upload/{model}")
    public R upload(@PathVariable String model, MultipartFile file) {
        DataProxy dataProxy = dataProxyInvoke.invoke(GlobalUtil.entityClassMap.get(model));
        List list ;
        if (dataProxy == null) {
            list = dataProxy.upload(model, file);
        } else {
            list =    myService.upload(model,file);
        }
        return R.ok(list);
    }

   public SearchParam getSearchParam(String model, JSONObject req){
       Class clazz = GlobalUtil.entityClassMap.get(model);
       SearchParam searchParam = req.toJavaObject(req, SearchParam.class);
       searchParam.setEntity(req.getObject("entity", clazz));
       return searchParam;
   }




}


